
package com.jf.cloud.search.feign;


import com.alibaba.fastjson.JSON;
import com.jf.cloud.api.feign.EsOrderFeignClient;
import com.jf.cloud.api.order.feign.OrderFeignClient;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.order.bo.EsOrderBO;
import com.jf.cloud.common.order.dto.OrderSearchDTO;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.search.constant.EsConstant;
import com.jf.cloud.search.constant.EsIndexEnum;
import com.jf.cloud.search.manager.OrderSearchManager;
import com.jf.cloud.search.util.EsSearchUtil;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.SearchHit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Hidden;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * ES订单操作
 * @author zz
 * @date 2020/12/07
 */
@RestController
@Hidden
public class EsOrderFeignController implements EsOrderFeignClient {
    private static final Logger log = LoggerFactory.getLogger(EsOrderFeignController.class);

    @Autowired
    private OrderFeignClient orderFeignClient;

    @Autowired
    private OrderSearchManager orderSearchManager;

    private static final Logger logger = LoggerFactory.getLogger(EsOrderFeignController.class);

    @Override
    public ServerResponseEntity<Void> updateOrder(Long orderId) {
        ServerResponseEntity<EsOrderBO> orderResponseEntity = orderFeignClient.saveMongoAndGetEsInfo(orderId);
        if (orderResponseEntity.isFail()) {
            throw new LuckException(orderResponseEntity.getMsg());
        }
        if (Objects.isNull(orderResponseEntity.getData())) {
            return null;
        }
        EsOrderBO esOrder = orderResponseEntity.getData();
        if (Objects.nonNull(esOrder)) {
            logger.info("更新订单信息-订单id为：{}，订单信息为：{}", orderId, JSON.toJSONString(esOrder));
            EsSearchUtil.esUpdate(esOrder.getOrderId(), EsIndexEnum.ORDER, esOrder);
        } else {
            // es相关的不需要报错，打印日志即可
            log.error("更新订单信息异常-订单id为：{}", orderId);
        }
        return ServerResponseEntity.success();
    }

    @Override
    public List<EsOrderBO> getUndeliveryOrder(OrderSearchDTO orderSearchDTO) {
        orderSearchDTO.setFetchSource(EsConstant.UN_DELIVERY_ORDER_FETCH_SOURCE);
        orderSearchDTO.setNotRefundStatus(1);
        String scrollId = null;
        List<EsOrderBO> result  = new ArrayList<>();
        // 设置查询超时时间
        Scroll scroll = new Scroll(TimeValue.timeValueMinutes(5L));
        SearchRequest searchRequest = orderSearchManager.buildScrollSearchRequest(orderSearchDTO, scroll);
        try{
            // 进行第一次滚动查询
            SearchResponse searchResponse = EsSearchUtil.search(searchRequest);
            scrollId = searchResponse.getScrollId();

            //记录要滚动的ID
            //滚动查询部分，将从第1001笔数据开始取
            SearchHit[] hitsScroll = searchResponse.getHits().getHits();
            for(SearchHit searchHit : hitsScroll){
                EsOrderBO esOrderBO = JSON.parseObject(searchHit.getSourceAsString(), EsOrderBO.class);
                result.add(esOrderBO);
            }
            while (hitsScroll != null && hitsScroll.length > 0) {
                //构造滚动查询条件
                SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId);
                searchScrollRequest.scroll(scroll);
                searchResponse = EsSearchUtil.scroll(searchScrollRequest);
                scrollId = searchResponse.getScrollId();
                hitsScroll = searchResponse.getHits().getHits();

            }

        } catch (Exception e) {
            logger.error("获取待发货的订单异常: {}",e);
            throw new LuckException("获取待发货的订单异常");
        } finally {
            if (Objects.nonNull(scrollId)) {
                //清除滚动，否则影响下次查询
                EsSearchUtil.clearScroll(scrollId);
            }

        }

        return result;
    }
}
